package ie.dkit.java3Demulation.drawer;

import java.awt.Graphics;

import ie.dkit.java3Demulation.objects.Line;

/**
 * @author Sebastian Ruehl
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
public class LineDrawer extends Drawer {

	/**
	 * Create a new LineDrawer
	 * @param graphics
	 * @param xMiddle
	 * @param ymiddle
	 */
	public LineDrawer(Graphics graphics, int xMiddle, int ymiddle) {
		super(graphics, xMiddle, ymiddle);
	}

	public void draw(Line line) {
		bresenham((int) line.getPointA().getX(), (int) line.getPointA().getY(),
				(int) line.getPointB().getX(), (int) line.getPointB().getY());
	}

	private void bresenham(int x1, int y1, int x2, int y2) {
		int dx, dy, incr1, incr2, xIncr, yIncr, d, x, y, tmp;

		dx = Math.abs(x2 - x1);
		dy = Math.abs(y2 - y1);

		if (dx > dy) // use x as incrementor
		{
			d = 2 * dy - dx;
			incr1 = 2 * dy;
			incr2 = 2 * (dy - dx);

			if (x1 > x2) // switch end-points
			{
				tmp = x1;
				x1 = x2;
				x2 = tmp;

				tmp = y1;
				y1 = y2;
				y2 = tmp;
			}

			if (y1 < y2) // either slope up or down
			{
				yIncr = 1;
			} else {
				yIncr = -1;
			}

			y = y1;

			for (x = x1; x <= x2; x++) {
				writePixel(x, y);
				if (d < 0) {
					d += incr1;
				} else {
					y += yIncr;
					d += incr2;
				}

			}
		} else // use y as incrementor
		// the code below is similar to the code above, except
		// that now calculations are
		// based on y changing at a faster rate than x is.
		{
			d = 2 * dx - dy;
			incr1 = 2 * dx;
			incr2 = 2 * (dx - dy);
			if (y1 > y2) // switch end-points
			{
				tmp = x1;
				x1 = x2;
				x2 = tmp;

				tmp = y1;
				y1 = y2;
				y2 = tmp;
			}
			if (x1 < x2) // either slope up or down
			{
				xIncr = 1;
			} else {
				xIncr = -1;
			}

			x = x1;

			for (y = y1; y <= y2; y++) {
				writePixel(x, y);
				if (d < 0) {
					d += incr1;
				} else {
					x += xIncr;
					d += incr2;
				}

			}
		}
	}
}
